package com.hjh.thread.semaphore;



/*
#######
1、Semaphore是java提供的一个并发工具；
  Semaphore经常用于限制获取某种资源的线程数量;


#######
2、Semaphore.java提供的常用方法
2.1、初始化

    #参数2表示有多少个资源可以获取
    Semaphore semaphore = new Semaphore(2);

2.2、获取还可以使用的资源个数
     int permits = semaphore.availablePermits()；

2.3、获取1个资源
     #获取一个资源，如果没有资源则阻塞
     semaphore.acquire();
2.4、释放资源

   #释放1个资源
   semaphore.release();

   #释放n个资源
   semaphore.release(n);


2.5、获取多个资源并且不可中断
    semaphore.acquireUninterruptibly(n);
    #释放n个资源
   semaphore.release(n);

2.6、尝试获取锁tryAcquire()
     这个方法不是阻塞的；
     如果获取到资源，则返回ture；
     不能获取到资源，则返回false;

2.7、当前线程在限定时间内，阻塞的尝试去获取permits个许可证。
     tryAcquire(permits,timeout,TimeUnit)

2.8、 drainPermits()
当前线程获得剩余的所有可用许可证。

2.9、 hasQueuedThreads()
判断当前Semaphore对象上是否存在正在等待许可证的线程。

2.10、 getQueueLength()

获取当前Semaphore对象上是正在等待许可证的线程数量。


2.11、Semaphore的初始值可以改变
Semaphore semaphore = new Semaphore(1);

其中的初始值 1 表示当前的信号量当前所允许访问的线程数；

并且这个初始值 1 是可以通过semaphore.acquire()或semaphore.release()函数进行改变的，

简而言之，就是信号量的初始值是可以进行改变的，不会因信号量的初始值而限制；


#######
3、Semaphore和锁的区别
3.1、锁是一个锁控制资源，Semaphore是控制多个资源；
3.2、锁是只能当前线程线程下释放，其他非当前线程不能释放；
     Semaphore不管是否是当前线程都可以释放；


#######
4、Semphore的底层实现原理
4.1、Semaphore内部主要通过AQS（AbstractQueuedSynchronizer）实现线程的管理；
     Semaphore通过内部类公平锁Sync和公平锁FairSync实现的；
     FairSync公平锁是Sync的子类，Sync是AQS的子类，所以Semaphore是通过AQS实现线程管理；

4.2、AQS有个volatile修饰的state变量，这个变量决定了Semaphore允许同时运行的线程数；
     private volatile int state;

4.3、acquire()就是获取state的资源，如果不小于等于0，则得到资源，并且state-1；
4.4、release()是释放资源，就是state加上1，如果state数量比初始值大，也要加上1；



 */